

package com.fg.object.oauth2;

import com.fg.common.constant.HttpConstant;
import com.fg.common.entity.Dto.UserDto;
import com.fg.common.util.Assert;
import com.fg.common.util.UserUtil;
import com.fg.room.service.UserService;
import com.fg.room.util.SpringUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * oauth2过滤器
 *
 * @author Mark sunlightcs@gmail.com
 */
@Slf4j
public class OAuth2Filter extends BasicHttpAuthenticationFilter {

    /**
     * 判断是否执行拦截
     * 暂定规则为除了放行跨域试探请求(请求方式为options，所以要求所有controller不能对外提供options类型的请求)
     * 其余全部拦截  被判定为需要拦截的请求会执行onAccessDenied方法
     *
     * @param request     request对象
     * @param response    response对象
     * @param mappedValue mappedValue
     * @return 是否允许访问
     */
    @SneakyThrows
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        //放行跨域options试探请求
        return HttpConstant.REQUEST_CROS_METHOD.equalsIgnoreCase(((HttpServletRequest) request).getMethod());
    }

    /**
     * 处理被拦截的请求
     *
     * @param request  request对象
     * @param response response对象
     * @return 是否拒绝访问
     * @throws Exception 异常
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        //执行登录
        return executeLogin(request, response);
    }

    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        String token = getToken((HttpServletRequest) request);
//        return !StringUtils.isBlank(token);
        return true;
    }

    /**
     * 从请求头获取token
     *
     * @param request 请求对象
     * @return token
     */
    private String getToken(HttpServletRequest request) {
        String token = request.getHeader(HttpConstant.TOKEN_HEADER_KEY_SYS);
        if (StringUtils.isBlank(token)) {
            token = request.getParameter(HttpConstant.TOKEN_HEADER_KEY_SYS);
        }
        Assert.assertNotNull(token, "请求token为空");
        UserService userService = (UserService) SpringUtil.getBean(UserService.class);
        UserDto user = userService.getUserByToken(token);
        user.setToken(token);
        UserUtil.user.set(user);
        return token;
    }
}
